#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <sw/redis++/redis++.h>

using namespace std;
using namespace sw::redis;
using namespace std::chrono_literals;

void testGetSet(sw::redis::Redis& redis)
{
    // 使用 optional 作为返回值
    cout << "using Get and Set" << endl;
    redis.flushall();
    redis.set("key1", "value1");
    redis.set("key2", "value2");
    redis.set("key3", "value3");

    auto value1 = redis.get("key1");
    if(value1)
        cout << value1.value() << endl;

    auto value2 = redis.get("key2");
    if(value2)
        cout << value2.value() << endl;

    auto value3 = redis.get("key3");
    if(value3)
        cout << value3.value() << endl;
}

void testExists(sw::redis::Redis& redis)
{
    cout << "using exists" << endl;
    redis.flushall();

    redis.set("key1", "value1");
    redis.set("key2", "value2");
    redis.set("key3", "value3");

    long long result;
    result = redis.exists("key1");
    cout << result << endl;

    result = redis.exists({"key1", "key2", "key3"});
    cout << result << endl;

    result = redis.exists("key4");
    cout << result << endl;
}

void testDel(sw::redis::Redis& redis)
{
    cout << "using del" << endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "111");
    redis.set("key3", "111");
    redis.set("key4", "111");
    redis.set("key5", "111");
    
    auto result = redis.del("key1");
    cout << result << endl;

    result = redis.del({"key2", "key3"});
    cout << result << endl;

    result = redis.del("key6");
    cout << result << endl;
}

void testKeys(sw::redis::Redis& redis)
{
    cout << "using keys" << endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "111");
    redis.set("key3", "111");
    redis.set("key4", "111");
    redis.set("key5", "111");

    vector<string> strs;
    auto it = back_inserter<vector<string>>(strs);
    redis.keys("*", it);

    for(auto& str : strs)
        cout << str << endl;
}

void testExpire(Redis& redis)
{
    // ttl chorno
    cout << "using expire and ttl" << endl;
    redis.flushall();

    redis.set("key", "111");
    // redis.expire("key", std::chrono::seconds(10));
    redis.expire("key", 10s);

    this_thread::sleep_for(5s);

    auto result = redis.ttl("key");
    cout << result << endl;
}

void testType(Redis& redis)
{
    cout << "using type" << endl;
    redis.flushall();

    redis.set("key1", "111");
    string ret = redis.type("key1");
    cout << "key1 " << ret << endl;

    redis.lpush("key2", "222");
    ret = redis.type("key2");
    cout << "key2 " << ret << endl;
}

int main()
{
    // 对板书做一下笔记 optional 迭代器如何实现解耦合
    // 可以去GitHub上看redis++的API文档
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    
    // ping()
    // std::string result = redis.ping();
    // cout << result << endl;
    // testGetSet(redis);
    // testExists(redis);
    // testKeys(redis);
    // testDel(redis);
    // testExpire(redis);
    testType(redis);
    return 0;
}